//
//  CLBuletoothPrivateProtocolTool.h
//  toroBracelet
//
//  Created by 丁益 on 16/11/14.
//  Copyright © 2016年 celi. All rights reserved.
//

#import <Foundation/Foundation.h>

#define GLOBAL_RECEIVE_BUFFER_SIZE 1024
#define GLOBAL_RESPONSE_BUFFER_SIZE 200

//是否有后续包，这里是指一大包(512byte)
typedef enum {
    no_follow_page = 0,  //没有后续包
    have_follow_page = 1 //有后续包
}Is_follow_page;

#define BLE_SEND_MAX_LENGTH    20    //每一包发送最大长度
#define L1_HEADER_MAGIC  (0xAB)      /*header magic number */
#define L1_HEADER_VERSION (0x00)     /*protocol version */
#define L1_HEADER_SIZE   (8)         /*L1 header length*/
#define L1_HEADER_FOLLOW_PACKAGE (0x40)  //后续包

/* define L1 header byte order */
#define L1_HEADER_MAGIC_POS                         (0)
#define L1_HEADER_PROTOCOL_VERSION_POS  (1)
#define L1_PAYLOAD_LENGTH_HIGH_BYTE_POS (2)         /* L1 payload lengh high byte */
#define L1_PAYLOAD_LENGTH_LOW_BYTE_POS  (3)
#define L1_HEADER_CRC16_HIGH_BYTE_POS   (4)
#define L1_HEADER_CRC16_LOW_BYTE_POS    (5)
#define L1_HEADER_SEQ_ID_HIGH_BYTE_POS  (6)
#define L1_HEADER_SEQ_ID_LOW_BYTE_POS   (7)

#define L2_HEADER_SIZE   (2)      /*L2 header length*/
#define L2_HEADER_VERSION (0x00)     /*L2 header version*/
#define L2_KEY_SIZE         (1)
#define L2_PAYLOAD_HEADER_SIZE (3)        /*L2 payload header*/
#define L2_FIRST_VALUE_POS (L2_HEADER_SIZE + L2_PAYLOAD_HEADER_SIZE)

#define L2_COMMAND_INDEX      0
#define L2_FIRST_KEY_INDEX    2   // 第一个frist key的数组下标位置
#define L2_FIRST_VALUE_LENGEH_INDEX 3
#define L2_FIRST_START_VALUE  5

/* This enum describe the current task type */
typedef enum {
    TASK_NONE = 0,
    TASK_DATA = 1,
    TASK_ACK = 2
}SEND_TASK_TYPE_T;

/* define version response */
typedef enum {
    DATA_PACKAGE = 0,
    RESPONSE_PACKAGE =  1,
}L1_PACKAGE_TYPE;

typedef enum {
    CONTENT_NONE = 0,
    CONTENT_HEADER = 1,
    CONTENT_DATA = 2,
    CONTENT_ACK = 3
}SEND_CONTENT_TYPE_T;


/* individual response buffer*/
struct Response_Buff_Type_t
{
    uint16_t sequence_id;
    uint8_t  check_success;
    uint8_t  isUsed;
};

#define MAX_SEND_TASK  (1)      /* for only one buffer */

typedef enum {
    DO_BOND = 0,
    DO_WAIT_BOND_COMMAND = 1
}USER_TIMER_COMMAND_t;

typedef enum{
    PRIVATE_NOT_BOND = 0,
    PRIVATE_BOND_SUCCESS = 1
} BLUETOOTH_BOND_STATE;

typedef enum  {
    SEND_FAIL   = 0,
    SEND_SUCCESS = 1,
    SEND_NO_WRITE_SEVERS = 2, //没有写服务
}SEND_STATUS;

typedef enum {
    WAIT_START = 0,
    WAIT_MESSAGE,
    MESSAGE_RESOLVE
}RECEIVE_STATE;

/* Command ID */
typedef enum {
    FIRMWARE_UPDATE_CMD_ID = 0x01,
    SET_CONFIG_COMMAND_ID = 0x02,
    BOND_COMMAND_ID = 0x03,
    NOTIFY_COMMAND_ID = 0x04,
    HEALTH_DATA_COMMAND_ID = 0x05,
    FACTORY_TEST_COMMAND_ID = 0x06,
    CONTROL_COMMAND_ID = 0x07,
    BLUETOOTH_LOG_COMMAND_ID = 0x0a,
    GET_STACK_DUMP          = 0x10,
    PAY_CARD_COMMAND_ID = 0x20,
    BAT_INFO_COMMAND_ID = 0x021,
    TEST_FLASH_READ_WRITE = 0xFE,
    TEST_COMMAND_ID = 0xFF
}BLUETOOTH_COMMUNICATE_COMMAND;

typedef enum  {
    KEY_TIME_SETTINGS   = 0x01,
    KEY_ALARM_SETTINGS  = 0x02,
    KEY_REQUEST_ALARM_SETTINGS  = 0x03,
    KEY_RETURN_ALARM_SETTINGS = 0x04,
    KEY_STEP_TARGET_SETTINGS = 0x05,
    KEY_PROFILE_SETTINGS = 0x10,
    KEY_DEV_LOSS_ALERT_SETTINGS = 0x20,
    KEY_PHONE_REMIND = 0x25,            //电话提醒
    KEY_SMS_REMIND = 0x27,                 //短信提醒
    KEY_WECHAT_REMIND = 0x28           //微信提醒
}SETTINGS_KEY; //设置命令

typedef enum  {
    KEY_REQUEST_DATA   = 0x01,
    KEY_RETURN_SPORTS_DATA  = 0x02,
    KEY_RETURN_SLEEP_DATA  = 0x03,
    KEY_MORE    = 0x04,
    KEY_RETURN_SLEEP_SETTING= 0x05,
    KEY_SET_STEPS_NOTIFY =0x06,
    KEY_DATA_SYNC_START= 0x07,
    KEY_DATA_SYNC_END =0x08,
    KEY_DAILY_DATA_SYNC = 0x09,
    KEY_LATEST_DATA_SYNC = 0x0A,
    KEY_SLEEP_TIME_QUANTM = 0x0B,
    KEY_REQUEST_SPORT_TODAY    = 0x0C,
    KEY_BREAK_SPORT_TODAY = 0x0d,
    KEY_REQUEST_SLEEP_TODAY     = 0x0e,
    KEY_BREAK_SLEEP_TODAY = 0x0f,
}SPORTS_KEY;

typedef enum {
    KEY_ENTER_FIRMWARE_UPDATE_MODE  = 0x01,
    KEY_ENTER_DFU_MODE_RET          = 0x02,
    KEY_GET_FIRMWARE_VERSION_INFO   = 0x11,
    KEY_RET_FIRMWARE_VERSION_INFO   = 0x12,
}FIRMWARE_UPDATE_KEY;

typedef enum {

    KEY_BIND_USER_REQUEST   = 0x01, //绑定用户请求
    KEY_BIND_USER_BACK      = 0x02, //绑定用户返回
    KEY_USER_LOGIN_REQUEST  = 0x03, //用户登陆请求
    KEY_USER_LOGIN_BACK     = 0x04, //用户登陆返回
    KEY_USER_UNBIND         = 0x05, //用户解除绑定
    KEY_USER_UNBIND_BACK    = 0x06  //用户解绑绑定返回
}BIND_KEY;

typedef enum {

    KEY_CARD_MONEY_REQUEST  = 0x01, //请求余额
    KEY_CARD_MONEY_BACK     = 0x02, //返回card 余额
    KEY_CARD_ID_REQUEST     = 0x03, //请求card ID
    KEY_CARD_ID_BACK        = 0x04, //返回card ID
    KEY_CARD_TOP_UP         = 0x05, //Pay card 充值
    KEY_CARD_TOP_UP_BACK    = 0x06, //返回 Pay card 充值
    KEY_CARD_TRADE_LIST     = 0x07, //请求交易列表
    KEY_CARD_TRADE_LIST_BACK= 0x08, //交易列表返回
}PAY_CARD_KEY;



typedef struct
{
    uint8_t version  :
    4;
    uint8_t ack_flag  :
    1;
    uint8_t err_flag  :
    1;
    uint8_t reserve  :
    2;
}
L1_version_def_t;

typedef union{
    L1_version_def_t version_def;
    uint8_t value;
}L1_version_value_t;

typedef enum
{
    CRC_SUCCESS = 0,
    CRC_FAIL = 1
}crc_check_result;

/* L1 header struct */
typedef struct
{
    uint8_t magic;
    uint8_t version;
    uint16_t payload_len;
    uint16_t crc16;
    uint16_t sequence_id;
}
L1Header_t;

/*async send operation callback*/
typedef void (*send_status_callback_t)(SEND_STATUS status );

/*Used by L1, used to send whole L1 package throw bluetooth */
typedef struct
{
    uint8_t *         content;   /* content to be send */
    send_status_callback_t                   callback;   /* send status callback */
    uint16_t          length;    /* content length */
    uint16_t             contentLeft;     /* content left for send*/
    uint16_t         sequence_id;        /* sequence id for this package*/
    uint8_t                         isUsed;    /* is the current struct used*/
    uint8_t             resendCount;     /* whole L1 package resend count */
}L1_Send_Content;


/*L1 version defination */
typedef struct
{
    L1_Send_Content * content;
    uint16_t        isUsed;
}L1_Header_Schedule_type_t;



typedef struct
{
    uint8_t*             content;    /* content to be send */
    send_status_callback_t   callback;   /* send status callback */
    uint16_t                 length;     /* content length */
}L2_Send_Content;


//typedef struct
//{
//    uint32_t year  :
//    6;
//    uint32_t month  :
//    4;
//    uint32_t day  :
//    5;
//    uint32_t hour  :
//    5;
//    uint32_t minute  :
//    6;
//    uint32_t second  :
//    6;
//}time_struct;


typedef struct
{
    uint32_t second  :
    6;
    uint32_t minute  :
    6;
    uint32_t hour  :
    5;
    uint32_t day  :
    5;
    uint32_t month  :
    4;
    uint32_t year  :
    6;
}time_struct;


typedef union{
    time_struct time_def;
    uint32_t value;
}time_struct_value_t;


typedef struct {
    uint64_t day_flag:
    7;
    uint64_t reserve:
    4;
    uint64_t numberId:
    3;
    uint64_t minute  :
    6;
    uint64_t hour  :
    5;
    uint64_t day  :
    5;
    uint64_t month  :
    4;
    uint64_t year  :
    6;
}alarm_struct;

typedef union{
    alarm_struct alarm_clock_def;
    uint64_t value;
}alarm_clock_struct_value_t;

/* Definend for send callback */
typedef void (*send_complete_callback_t)(void *context,SEND_TASK_TYPE_T type);

typedef  struct
{
    send_complete_callback_t callback;
    void * context;
    SEND_TASK_TYPE_T task_type;
}
SendCompletePara;

typedef void(^askBlock)(SEND_STATUS askStatus);
typedef void(^resultBlock)(Byte *recData, uint16_t length) ;

@interface CLBuletoothPrivateProtocolTool : NSObject

@property (nonatomic, copy) askBlock receiveAskBlock;
@property (nonatomic, copy) resultBlock receiveResultBlock;

- (void)sendBleData:(L2_Send_Content *) L2sendData dataLength:(NSInteger) length receiveAskBlock:(askBlock)receiveAskblock receiveResultBlock:(resultBlock)receiveResultBlock;

@end
